﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using DomainDriver.CommonUtilities.Collections;

namespace DomainDriver.CommonUtilities.UnitTests.Collections
{
    [TestFixture]
    public class CollectionUtilitiesTests
    {
        [Test]
        public void VerifyMethod_AreUnorderedCollectionsEqual()
        {
            List<int> firstList = new List<int>();
            List<int> secondList = new List<int>();

            bool areListsEqual = CollectionUtilities.AreUnorderedCollectionsEqual<int>(firstList, secondList);
            Assert.AreEqual(true, areListsEqual);

            firstList.Add(1);

            areListsEqual = CollectionUtilities.AreUnorderedCollectionsEqual<int>(firstList, secondList);
            Assert.AreEqual(false, areListsEqual);

            secondList.Add(1);

            areListsEqual = CollectionUtilities.AreUnorderedCollectionsEqual<int>(firstList, secondList);
            Assert.AreEqual(true, areListsEqual);

            secondList.Add(5);

            areListsEqual = CollectionUtilities.AreUnorderedCollectionsEqual<int>(firstList, secondList);
            Assert.AreEqual(false, areListsEqual);

            firstList.Add(5);

            areListsEqual = CollectionUtilities.AreUnorderedCollectionsEqual<int>(firstList, secondList);
            Assert.AreEqual(true, areListsEqual);
        }

        [Test]
        public void VerifyMethod_AreUnorderedDictionariesEqual()
        {
            Dictionary<int, string> firstDictionary = new Dictionary<int, string>();
            Dictionary<int, string> secondDictionary = new Dictionary<int, string>();

            bool areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(true, areDictionariesEqual);

            firstDictionary.Add(1, "one");

            areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(false, areDictionariesEqual);

            secondDictionary.Add(1, "one");

            areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(true, areDictionariesEqual);

            secondDictionary.Add(5, "five");

            areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(false, areDictionariesEqual);

            firstDictionary.Add(5, "five");

            areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(true, areDictionariesEqual);

            secondDictionary[5] = "four";

            areDictionariesEqual = CollectionUtilities.AreUnorderedDictionariesEqual<int, string>(firstDictionary, secondDictionary);
            Assert.AreEqual(false, areDictionariesEqual);
        }

        [Test]
        public void VerifyGetMinAndMaxValue()
        {
            CheckGetMinAndMaxValues(-11, 2, 55);
            CheckGetMinAndMaxValues(0, 2, 55);
            CheckGetMinAndMaxValues(4, 66, 55);
        }

        protected void CheckGetMinAndMaxValues(int value1, int value2, int value3)
        {
            int expectedMax = (value1 > value2) ? value1 : value2;
            expectedMax = (expectedMax > value3) ? expectedMax : value3;
            int expectedMin = (value1 < value2) ? value1 : value2;
            expectedMin = (expectedMin < value3) ? expectedMin : value3;

            IComparer<int> comparer = Comparer<int>.Default;
            List<int> collection = new List<int>();
            collection.Add(value1);
            collection.Add(value2);
            collection.Add(value3);
            List<StructWrapper<int>> collectionOfWrappers = new List<StructWrapper<int>>();
            collectionOfWrappers.Add(new StructWrapper<int>(value1));
            collectionOfWrappers.Add(new StructWrapper<int>(value2));
            collectionOfWrappers.Add(new StructWrapper<int>(value3));

            int actualMin = CollectionUtilities.GetMinValue<int>(collection).Value;
            Assert.AreEqual(expectedMin, actualMin);
            actualMin = CollectionUtilities.GetMinValue<int>(collection, comparer).Value;
            Assert.AreEqual(expectedMin, actualMin);
            actualMin = CollectionUtilities.GetMinValue<int, StructWrapper<int>>(collectionOfWrappers, (StructWrapper<int> obj) => obj.Value).Value;
            Assert.AreEqual(expectedMin, actualMin);

            int actualMax = CollectionUtilities.GetMaxValue<int>(collection).Value;
            Assert.AreEqual(expectedMax, actualMax);
            actualMax = CollectionUtilities.GetMaxValue<int>(collection, comparer).Value;
            Assert.AreEqual(expectedMax, actualMax);
            actualMax = CollectionUtilities.GetMaxValue<int, StructWrapper<int>>(collectionOfWrappers, (StructWrapper<int> obj) => obj.Value).Value;
            Assert.AreEqual(expectedMax, actualMax);
        }
    }
}